/* TabView.h
Michael Zahniser, 01/08/09

Header file for the TabView class, which is a portion of a user interface that manages
a set of tabbed views, all stacked on top of each other.

NOTE: A TabView could also be used like the Windows task bar to show a list of all
open windows. It is not _required_ that a tab be directly below the TabView.

TODO: Allow tabs to have a color specified?
*/

#ifndef __MZ_TAB_VIEW_H__
#define __MZ_TAB_VIEW_H__

#include "View.h"
#include "Font.h"
#include "_common/Callback.h"

#include <list>

using std::list;



// A TabView registers itself as the callback for when views are removed from the interface.
class TabView : public View, public CallbackT<const View *> {
public:
	// Create a TabView, specifying its height. This only makes a difference if
	// you plan to call Add(name, view, gui) to automatically place views.
	// If the given height is negative, the tab bar is assumed to be placed at the
	// bottom of the window instead of at the top.
	TabView(int height = 0);

	// Add a tab for the given view. Optionally, an interface can be specified too;
	// if it is, the view is added to that interface filling the entire space below
	// this tab bar. If more complex placement is needed, add the view to the
	// interface by hand.
	void Add(const string &name, View *view, Interface *gui = NULL);
	// Set the color of the tab corresponding to the given view.
	void SetColor(View *view, int red, int green, int blue);

	// Callback function for when a View is removed from the interface:
	virtual void operator()(const View *view);


protected:
	// Initialize a view, given the command line arguments for the program.
	// If the view cannot be initialized, this function should return false.
	// NOTE: SDL may not be initialized yet when a View's constructor is called,
	// so all initialization using SDL should be done here instead.
	virtual bool Initialize(const Surface &surface);

	// Handle an event. If the event involves (x, y) coordinates, they have been
	// translated such that (0, 0) is the top left corner of this View.
	// This function should return false if this view does not support the given
	// event and wants other views to have a chance to handle it.
	virtual bool Handle(const SDL_Event &event);

	// Draw the view in the given surface. The surface is passed as a (shallow)
	// copy so that it is impossible for derived classes to modify View::surface
	// to point to anything other than what Interface assigns to it.
	virtual void Draw(Surface surface) const;


private:
	class Tab {
	public:
		Tab(const string &name, View *view)
			: name(name), view(view), endX(0), red(255), green(255), blue(255)
		{
		}

		void SetColor(int r, int g, int b)
		{
			red = r;
			green = g;
			blue = b;
		}

		string name;
		View *view;
		int endX;
		// The color of this tab.
		int red;
		int green;
		int blue;
	};


private:
	void ActivateView(Interface *gui = NULL);


private:
	mutable list<Tab> tabs;
	list<Tab>::iterator active;

	Font font;
	Font greyFont;

	// The height of the tab bar.
	int height;
	// The position at which views should be added.
	int bottom;
};



#endif
